#pragma once
#include "ReadsMapping.h"
#include "MappingResult.h"
#include "LongReadInBits.h"
#include "ShortReadUtil.h"
#include <algorithm>
#include <limits>
using namespace std;

// int getDelAlignmentsInParallel(vector<string> readSetsList,CGenome_Index_TableQ& indexTable, MappingOpts P);

class  CDelMappingsQ
{
public:
    CDelMappingsQ();
    ~CDelMappingsQ();
    void clear(void);
    vector<CMappingResult> delAlignments;
    void update(CMappingResult &m, bool bUniqueDelMapOnly, bool bAllDelMap);
    void push_back(CMappingResult &m);
    int minDisScore;
    unsigned int minDiff;
    const static int MAX_ALIGNMENT_NO = 5;
    bool bAmbiguousDelMapping;
};

class CReadsDelMapping : public CReadsMapping
{
public:
    CReadsDelMapping(void);
    CReadsDelMapping(const MappingOpts P);
    ~CReadsDelMapping(void);
    int getDelAlignments(const CGenome_Index_TableQ& table, CLongReadsSet& readSet);
    int locateDelAlignments(const CGenome_Index_TableQ& table, CLongReadInBits & read,\
                            const char* readName, const char* pQScore);
    int examDelAlignments4aRead(const CGenome_Index_TableQ& table, CMappingResult& m);
    bool examDelAlignment(CSeqInBits& ref,  CMappingResult& m, unsigned int misT = 10);
    void printInDelAlignStats(ostream& out, string readSetName, unsigned int uiSubThreshold);

protected:
    int dealForwardDelAlignment (const CGenome_Index_TableQ& table, CMappingResult& m, CDelMappingsQ& delMappingQ) ;
    int dealReverseDelAlignment (const CGenome_Index_TableQ& table, CMappingResult& m, CDelMappingsQ& delMappingQ) ;
    void initialization(void);
    inline void bookKeepDelMapping(bool sepMore, bool sepLess);
    int noDelMapping;
    int noOfDelSepMore;
    int noOfDelSepLess;
    int noOfDelSepMoreAndLess;
    int noOfAmbiguousDelMapping;
private:
    // private function called by public examDelAlignment to exam the 50 comb of deletion
    int findBestSplicedSite(const char*  ref1,  const char*  ref2, CMappingResult& m);
    bool findSplicedSite(const char*  ref1,  const char*  ref2, CMappingResult& m, int misT = 10);

};
inline void CReadsDelMapping::bookKeepDelMapping(bool sepMore, bool sepLess)
{
    if (sepMore && sepLess) {
        noOfDelSepMoreAndLess++;
    } else if (sepMore) {
        noOfDelSepMore++;
    } else if (sepLess) {
        noOfDelSepLess++;
    }
}

inline void getSingleMappingInfo(CMappingResult &m, CAlignmentsQ &q, int mappingIndex);
void getLongReadSeqNQscores(CMappingResult &m,  CLongReadInBits& read, const char* QScores);
void sortAnchorByHitPos(CAlignmentsQ& q);
// int getMismatchScore(const char* ref, const char* seq, const char* scores, int length);
int getMismatchScore(const char* ref, const char* seq, const char* scores, int start, int length);
int getSepCigarStr(CMappingResult& m, int splicePos, int anchorL); // The funciton should belong to m
int getMEMEScore4aMap(CMappingResult& m, int splicePos);
int getMEMEScore(int length, int mismatches);
int getSpliceAlignedRef(const char* ref1,  const char*  ref2, int splicePos, int refLength, char* caRefBuf);

